package org.rslai.socket.testtool.isocket;

import java.io.*;
import java.net.*;

/**
 * IM 创建连接并且处理接收、发送数据
 * @author rslai
 *
 */
class ISocketIM extends ISocket {
	protected BufferedReader readBoundChar; // 得到字符输入流，按 char（位数根据系统而定） 读入

	/**
	 * 根据输入的参数建立一个Socket连接
	 * @param server 服务器IP或域名
	 * @param port 服务端口
	 * @param charset 传送信息的字符集
	 * @throws IOException
	 */
	public ISocketIM(String server, int port, String charset) throws IOException {
		super(charset);

		try {
			// 创建指定 Socket 链接
			clientSocket = new Socket(server, port);
			logger.info("clientSocket: " + clientSocket);

			writeBound = new DataOutputStream(clientSocket.getOutputStream()); // 得到输出流
			readBoundChar = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); // 得到字符输入流，按 char（位数根据系统而定） 读入
		} catch (UnknownHostException uhe) {
			logger.info("UnknownHostException: " + uhe);
		} catch (IOException ioe) {
			System.err.println("IOException: " + ioe);
			throw ioe;
		}
	}

	/**
	 * 关闭打开 Socket
	 */
	public void close() throws Exception {
		writeBound.close();
		readBoundChar.close();
		clientSocket.close();
	}

	/**
	 * 从服务器接收信息，按html格式接收
	 * @return 返回接收到的数据
	 * @throws Exception
	 */
	public ReceiveData receive() throws Exception{
		ReceiveData receiveData = new ReceiveDataIM();

		receiveData.setHead(receiveHead()); // 取得服务器传回的数据头信息
		receiveData.setBody(receiveBody(receiveData.getBodyLength())); // 取得服务器传回的数据体信息

		logger.debug("receive : \r\n" + receiveData.toString());

		return receiveData;
	}

	/**
	 * 取得服务器传回的数据头信息，按html格式接收
	 * @param headdata
	 * @return
	 * @throws Exception
	 */
	private StringBuffer receiveHead() throws Exception{
		boolean state = true;
		StringBuffer receiveHead = new StringBuffer();

		// 接收到数据的头信息
		String receiveMessage;
		while(true) {
			receiveMessage = readBoundChar.readLine();
			if (receiveMessage == null) {
				break;
			} else {
				if (receiveMessage.length() == 0) {
					break;
				} else {
					if (state) {
						state = false;
					}
					receiveHead.append(receiveMessage + "\r\n");
				}
			}
		}

		return receiveHead;
	}

	/**
	 * 按指定长度读取体信息
	 * @param lenght 体信息的长度
	 * @return 读到的体信息
	 * @throws Exception
	 */
	protected StringBuffer receiveBody(int lenght) throws Exception {
		StringBuffer bodyStrBuf = new StringBuffer(); // 保存读到的数据

		while(lenght > 0) {
			int readChar = readBoundChar.read(); // 读入读入一个字符
			bodyStrBuf.append((char)readChar);
			if (readChar > 255 && readChar < 65533) {
				lenght = lenght - 2;
			} else {
				lenght = lenght -1;
			}
		}

/*
		StringBuffer bodyStrBuf = new StringBuffer(); // 保存读到的数据

		while (true) {
			// 设置本次读入长度
			byte[] tmp;
			if (lenght > bufSize) {
				tmp = new byte[bufSize];
			} else {
				tmp = new byte[lenght];
			}

			// 读取指定长度的byte
			int len = readBoundByte.read(tmp);
			if (len > 0) {
				lenght = lenght - len;
				byte [] getByte = new byte[len];

				System.arraycopy(tmp, 0, getByte, 0, len);
				bodyStrBuf.append(new String(getByte, charset)); // 转为字符添加到输出数据中
			}

			// 判断读完后退出接收
			if (lenght <= 0) {
				break;
			}
		}
*/

		return bodyStrBuf;
	}

}